﻿using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;

namespace HostServicePhoneCommands.AppConfig
{
    public class GetCustomConfigSection
    {
        public static T GetServiceSettings<T>(string configPath, string customSection)
        {
            return GetServiceSettings<T>(configPath,
            // ReSharper disable AssignNullToNotNullAttribute
            new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName,
            customSection);
            // ReSharper restore AssignNullToNotNullAttribute
        }

        public static T GetServiceSettings<T>(string configPath, string customSectionHandlerAsseblyPath,
                                              string customSection)
        {
            var xmlDoc = new XmlDocument();
            var className = string.Empty;
            var assemblyName = string.Empty;

            if (!new FileInfo(configPath).Exists)
            {
                throw new FileNotFoundException(configPath);
            }

            xmlDoc.Load(configPath);

            foreach (var node in
                xmlDoc.GetElementsByTagName("configSections")[0].ChildNodes.Cast<XmlNode>().Where(
                // ReSharper disable PossibleNullReferenceException
                    node => node.Attributes["name"] != null && customSection.Equals(node.Attributes["name"].Value)))
            // ReSharper restore PossibleNullReferenceException
            {
                // ReSharper disable PossibleNullReferenceException
                className = node.Attributes["type"].Value.Split(',')[0].Trim();
                // ReSharper restore PossibleNullReferenceException
                assemblyName = node.Attributes["type"].Value.Split(',')[1].Trim() + ".exe";

                if (!new FileInfo(Path.Combine(customSectionHandlerAsseblyPath, assemblyName)).Exists)
                {
                    throw new FileNotFoundException(Path.Combine(customSectionHandlerAsseblyPath, assemblyName));
                }

                break;
            }

            var classType =
                Assembly.LoadFrom(Path.Combine(customSectionHandlerAsseblyPath, assemblyName)).GetType(className);
            var customConfig = (IConfigurationSectionHandler)Activator.CreateInstance(classType, true);

            var classresult = customConfig.Create(null, null, xmlDoc.GetElementsByTagName(customSection)[0]);

            return (T)classresult;
        }
    }
}